import config from '../config/index.js'

/**
 * 网络请求封装
 * @param {Object} options 请求参数
 * @param {string} options.url 请求地址
 * @param {string} options.method 请求方法
 * @param {Object} options.data 请求数据
 * @param {Object} options.header 请求头
 * @param {boolean} options.loading 是否显示loading
 * @param {boolean} options.showError 是否显示错误提示
 */
const request = (options = {}) => {
  // 显示loading
  if (options.loading !== false) {
    uni.showLoading({
      title: '加载中...',
      mask: true
    })
  }
  
  // 合并请求头
  const header = {
    ...config.headers,
    ...options.header
  }
  
  // 处理token
  const token = uni.getStorageSync('token')
  if (token) {
    header['Authorization'] = `Bearer ${token}`
  }
  
  // 构建完整URL
  let url = options.url
  if (url.indexOf('http') !== 0) {
    url = config.baseURL + url
  }
  
  return new Promise((resolve, reject) => {
    uni.request({
      url,
      method: options.method || 'GET',
      data: options.data || {},
      header,
      timeout: options.timeout || config.timeout,
      success: (res) => {
        // 隐藏loading
        if (options.loading !== false) {
          uni.hideLoading()
        }
        
        // 请求成功
        if (res.statusCode === 200) {
          // 根据业务状态码处理
          if (res.data.code === 200 || res.data.success === true) {
            resolve(res.data)
          } else {
            // 业务错误处理
            handleError(res.data, options)
            reject(res.data)
          }
        } else if (res.statusCode === 401) {
          // 未授权，跳转登录
          handleUnauthorized()
          reject(res)
        } else {
          // HTTP错误
          const errorMsg = `请求失败: ${res.statusCode}`
          if (options.showError !== false) {
            uni.showToast({
              title: errorMsg,
              icon: 'none'
            })
          }
          reject({ message: errorMsg, ...res })
        }
      },
      fail: (err) => {
        // 隐藏loading
        if (options.loading !== false) {
          uni.hideLoading()
        }
        
        // 网络错误处理
        let errorMsg = '网络请求失败'
        if (err.errMsg.includes('timeout')) {
          errorMsg = '请求超时，请检查网络'
        } else if (err.errMsg.includes('fail')) {
          errorMsg = '网络连接失败，请检查网络'
        }
        
        if (options.showError !== false) {
          uni.showToast({
            title: errorMsg,
            icon: 'none'
          })
        }
        
        reject({ message: errorMsg, ...err })
      }
    })
  })
}

/**
 * 处理业务错误
 * @param {Object} data 响应数据
 * @param {Object} options 请求选项
 */
const handleError = (data, options) => {
  const message = data.message || data.msg || '操作失败'
  
  if (options.showError !== false) {
    uni.showToast({
      title: message,
      icon: 'none'
    })
  }
}

/**
 * 处理未授权
 */
const handleUnauthorized = () => {
  // 清除token
  uni.removeStorageSync('token')
  
  // 显示提示
  uni.showToast({
    title: '登录已过期，请重新登录',
    icon: 'none'
  })
  
  // 跳转登录页
  setTimeout(() => {
    uni.navigateTo({
      url: '/pages/login/login'
    })
  }, 1500)
}

/**
 * GET请求
 * @param {string} url 请求地址
 * @param {Object} params 请求参数
 * @param {Object} options 其他选项
 */
export const get = (url, params = {}, options = {}) => {
  return request({
    url,
    method: 'GET',
    data: params,
    ...options
  })
}

/**
 * POST请求
 * @param {string} url 请求地址
 * @param {Object} data 请求数据
 * @param {Object} options 其他选项
 */
export const post = (url, data = {}, options = {}) => {
  return request({
    url,
    method: 'POST',
    data,
    ...options
  })
}

/**
 * PUT请求
 * @param {string} url 请求地址
 * @param {Object} data 请求数据
 * @param {Object} options 其他选项
 */
export const put = (url, data = {}, options = {}) => {
  return request({
    url,
    method: 'PUT',
    data,
    ...options
  })
}

/**
 * DELETE请求
 * @param {string} url 请求地址
 * @param {Object} params 请求参数
 * @param {Object} options 其他选项
 */
export const del = (url, params = {}, options = {}) => {
  return request({
    url,
    method: 'DELETE',
    data: params,
    ...options
  })
}

/**
 * 文件上传
 * @param {string} url 上传地址
 * @param {string} filePath 文件路径
 * @param {Object} formData 额外参数
 * @param {Object} options 其他选项
 */
export const upload = (url, filePath, formData = {}, options = {}) => {
  // 显示loading
  if (options.loading !== false) {
    uni.showLoading({
      title: '上传中...',
      mask: true
    })
  }
  
  // 构建完整URL
  if (url.indexOf('http') !== 0) {
    url = config.baseURL + url
  }
  
  // 处理token
  const token = uni.getStorageSync('token')
  const header = {}
  if (token) {
    header['Authorization'] = `Bearer ${token}`
  }
  
  return new Promise((resolve, reject) => {
    uni.uploadFile({
      url,
      filePath,
      name: options.name || 'file',
      formData,
      header,
      timeout: options.timeout || config.timeout * 2, // 上传超时时间加倍
      success: (res) => {
        // 隐藏loading
        if (options.loading !== false) {
          uni.hideLoading()
        }
        
        // 解析响应数据
        let data = res.data
        try {
          data = JSON.parse(res.data)
        } catch (e) {
          // 非JSON格式数据
        }
        
        // 请求成功
        if (res.statusCode === 200) {
          if (data.code === 200 || data.success === true) {
            resolve(data)
          } else {
            handleError(data, options)
            reject(data)
          }
        } else {
          const errorMsg = `上传失败: ${res.statusCode}`
          if (options.showError !== false) {
            uni.showToast({
              title: errorMsg,
              icon: 'none'
            })
          }
          reject({ message: errorMsg, ...res })
        }
      },
      fail: (err) => {
        // 隐藏loading
        if (options.loading !== false) {
          uni.hideLoading()
        }
        
        let errorMsg = '上传失败'
        if (err.errMsg.includes('timeout')) {
          errorMsg = '上传超时，请检查网络'
        } else if (err.errMsg.includes('fail')) {
          errorMsg = '网络连接失败，请检查网络'
        }
        
        if (options.showError !== false) {
          uni.showToast({
            title: errorMsg,
            icon: 'none'
          })
        }
        
        reject({ message: errorMsg, ...err })
      }
    })
  })
}

export default {
  request,
  get,
  post,
  put,
  delete: del,
  upload
}